
#ifndef _SGKS_MDI_H_
#define _SGKS_MDI_H_


#include <linux/module.h>
#include <linux/delay.h>
#include <linux/dma-mapping.h>
#include <linux/mman.h>
#include <linux/idr.h>
#include <linux/fb.h>
#include <linux/spi/spi.h>
#include <linux/proc_fs.h>
#include <linux/hrtimer.h>
#include <linux/ipcbus.h>
#include <linux/random.h>
#include <linux/miscdevice.h>
#include <linux/bitrev.h>
#include <linux/ktime.h>
#include <linux/i2c.h>
#include <asm/uaccess.h>
#include <plat/fb.h>
#include <plat/syncproc.h>
#include <plat/highres_timer.h>
#include <plat/cache.h>
#include <plat/event.h>
#include <mach/spi.h>
#include <mach/event.h>
#include <mach/board.h>
#include <mach/rct.h>
#include <mach/io.h>
#include <linux/kdev_t.h>
#include <sgks6802.h>

#include "../../mdi-common/mdi_common.h"

#define	MDI_RGB_AAA_DATA_BLOCK			(2048)
#define	MDI_CFA_AAA_DATA_BLOCK			(12416)
#define SGKS_DSP_CMD_SIZE             128
#define SGKS_DSP_MAX_CMD_NUM          31
#define clean_d_cache           sgks_cache_clean_range
#define invalidate_d_cache      sgks_cache_inv_range

#define SGKS_CRYPTO_ENCRPT    0
#define SGKS_CRYPTO_DECRPT    1

#define CRYPTO_VA_BASE                  SGKS6802_VA_CRYPT_UNIT
#define CRYPTO_VA_REG(x)                (CRYPTO_VA_BASE + (x))
#define REG_CRYPTO_DES_KEY              CRYPTO_VA_BASE


#define REG_CRYPTO_DES_INPUT            CRYPTO_VA_REG(0x008) /* read/write */


#define REG_CRYPTO_DES_OPCODE           CRYPTO_VA_REG(0x010) /* read/write */
#define REG_CRYPTO_SHIFT_BYTE           CRYPTO_VA_REG(0x0A0) /* read/write */
#define REG_CRYPTO_START_LENGTH           CRYPTO_VA_REG(0x09c) /* read/write */



#define REG_CRYPTO_DES_OUTPUT_RDY       CRYPTO_VA_REG(0x014) /* read */

#define REG_CRYPTO_DES_OUTPUT           CRYPTO_VA_REG(0x018) /* read */
#define REG_CRYPTO_DES_INTERRUPT        CRYPTO_VA_REG(0x000) /* read/write */

#define REG_CRYPTO_AES_128_KEY          CRYPTO_VA_REG(0x074) /* read/write */

#define REG_CRYPTO_AES_192_KEY          CRYPTO_VA_REG(0x064) /* read/write */

#define REG_CRYPTO_AES_256_KEY          CRYPTO_VA_REG(0x04c) /* read/write */

#define REG_CRYPTO_AES_INPUT            CRYPTO_VA_REG(0x084) /* read/write */
#define REG_CRYPTO_AES_OPCODE           CRYPTO_VA_REG(0x02C) /* read/write */
#define REG_CRYPTO_AES_OUTPUT_RDY       CRYPTO_VA_REG(0x088) /* read */

#define REG_CRYPTO_AES_OUTPUT           CRYPTO_VA_REG(0x098) /* read */
#define REG_CRYPTO_AES_INTERRUPT        CRYPTO_VA_REG(0x028) /* read/write */
#define REG_CRYPTO_EFUSE_BOOT_SW_DIS    CRYPTO_VA_REG(0x098) /* read/write */

#define MAX_VI_IRQ_NUM    (4)
#define DSP_TO_PHYS(addr)       (u32)((u32)(addr) )
#define DSP_TO_SGKSVIRT(addr)     phys_to_virt(DSP_TO_PHYS((u32)addr))

#define local_irq_save(x)					\
	({							\
		unsigned long temp;				\
		__asm__ __volatile__(					\
		                                        "mrs	%0, cpsr		@ local_irq_save\n"	\
		                                        "	orr	%1, %0, #128\n"					\
		                                        "	msr	cpsr_c, %1"					\
		                                        : "=r" (x), "=r" (temp)					\
		                                        :							\
		                                        : "memory");						\
	})

/*
 * restore saved IRQ & FIQ state
 */
#define local_irq_restore(x)					\
	__asm__ __volatile__(					\
	                                        "msr	cpsr_c, %0		@ local_irq_restore\n"	\
	                                        :							\
	                                        : "r" (x)						\
	                                        : "memory")



#define CHECK_PARAM_SIZE(name, src_size, dst_size, rt_val)\
do\
{\
	if (src_size != dst_size)\
	{\
		printk("param size error! [%s]\n",name);\
		return rt_val;\
	}\
}while(0)

#define WAIT_FOR_COMPL_TIMEOUT(compl_name, compl, time, ret)  			\
do																			\
{																			\
	*ret = 0;																\
	unsigned long leavetime = wait_for_completion_timeout(compl, time);	\
	if (leavetime == 0)														\
	{																		\
		*ret = -1;															\
		printk("err: wait compl [time out] %s!\n",compl_name);					\
	}																		\
	else if (leavetime < 0)												\
	{																		\
		*ret = -1;															\
		printk("err: wait compl [err] %s!\n",compl_name);						\
	}																		\
}while(0)


#define CHECK_NULL_POINTER(ptr,rt_val)\
do\
{\
	if (ptr == NULL)\
	{\
		printk("NULL_POINTER!\n");\
		return rt_val;\
	}\
}while(0)

typedef struct _DBGPARAM
{
        unsigned char   lpszName[32];           // @field Name of module
        unsigned char   rglpszZones[16][32];    // @field names of zones for first 16 bits
        unsigned long   ulZoneMask;             // @field Current zone Mask
} DBGPARAM, *LPDBGPARAM;

extern  DBGPARAM    dpCurSettings;
#define DEBUGZONE(n)  (dpCurSettings.ulZoneMask&(0x00000001<<(n)))

#define DEBUG

#ifdef SHIP_BUILD
#define ERRORMSG(cond,printf_exp) ((void)0)
#define RETAILMSG(cond,printf_exp) ((void)0)
#else // SHIP_BUILD
#ifdef DEBUG
#define DEBUGMSG(cond,printf_exp)   \
   ((void)((cond)?(printk printf_exp),1:0))
#define RETAILMSG(cond,printf_exp)   \
   ((cond)?(printk printf_exp),1:0)
#else // RELEASE
#define DEBUGMSG(cond,printf_exp) ((void)0)
#define RETAILMSG(cond,printf_exp)   \
   ((cond)?(printk printf_exp),1:0)
#endif // DEBUG
#endif

#define SGKS_MDI_MAX_DEFAULT_CMD_NUM   31
#define SGKS_MDI_CMD_SIZE             128    // a cmd  fixed size
#define mdi_error(S...)         printk("mdi error: "S)
#define NUM_BS_DESC                  (512)
typedef enum __sgks_dsp_operation_mode
{
    DSP_ENCODE_MODE      = 0x00,
    DSP_DECODE_MODE      = 0x01,
    DSP_RESET_MODE       = 0x02,
    DSP_UNKNOWN_MODE     = 0x03,
    DSP_QUICKLOGO_MODE   = 0x04,
}sgks_dsp_operation_mode_e;

typedef enum __sgks_encode_state
{
    ENC_IDLE_STATE               = 0x00,
    ENC_BUSY_STATE               = 0x01,
    ENC_PAUSE_STATE              = 0x02,
    ENC_FLUSH_STATE              = 0x03,
    ENC_RJPEG_STOP_STATE         = 0x04,
    ENC_RJPEG_RESUMABLE_STATE    = 0x05,
    ENC_UNKNOWN_STATE            = 0xFF,
} sgks_encode_state_e;

typedef enum __sgks_encode_mode
{
    DSP_STOP_V_ENC       = 0,    /* Nothing (not preview) is running in this mode. */
    DSP_ENC_PRE_MODE     = 1,    /* H264 encoding + preview. */
    DSP_SJPEG_PRE_MODE   = 2,    /* JPEG capture + preview. */
    DSP_MJPEG_PRE_MODE   = 3,    /* Real-time Motion JPEG + preview. */
    DSP_3A_DATA_MODE     = 4,    /* Gather 3A data. No preview. */
    DSP_ROW_DATA_MODE    = 5,    /* capture raw data from sensor or memory, generate
                                   preview, and jpeg encode the main picture and thumbnail. */
    DSP_TIMER_MODE       = 6,
    DSP_ENC_UNKNOWN_MODE = 7,
} sgks_encode_mode_e;

typedef enum __sgks_encode_params
{
    ENC_H264_QP_MIN               = 0,
    ENC_H264_QP_MAX               = 51,

    ENC_INVALID_FRAME_TIME_U64    = 0xFFFFFFFFFFFFFFFFLL,
    ENC_INVALID_NONREF_INDEX      = 0xFFFFFFFF,
    ENC_INVALID_REF_FRAME_COUNT   = 0xFFFFFFFF,
    ENC_INVALID_CALC_UNIT_SECONDS = 0xFFFFFFFF,
    ENC_INVALID_CALC_UNIT_FRAMES  = 0xFFFFFFFF,

    ENC_INVALID_PTS               = 0xc0c0c0c0,
    ENC_INVALID_PTS_U64           = 0xc0c0c0c0c0c0c0c0LL,
} sgks_encode_params_e;

typedef enum __sgks_dsp_pic_type
{
    DSP_PIC_TYPE_MJPEG_FRAME        = 0,
    DSP_PIC_TYPE_IDR_FRAME          = 1,
    DSP_PIC_TYPE_I_FRAME            = 2,
    DSP_PIC_TYPE_P_FRAME            = 3,
    DSP_PIC_TYPE_B_FRAME            = 4,
    DSP_PIC_TYPE_JPEG_STREAM        = 5,
    DSP_PIC_TYPE_JPEG_THUMBNAIL     = 6,
} sgks_dsp_pic_type_e;

typedef enum __sgks_enc_pic_type
{
    ENC_IDR_FRAME           = 1,
    ENC_I_FRAME             = 2,
    ENC_P_FRAME             = 3,
    ENC_B_FRAME             = 4,
    ENC_JPEG_STREAM         = 5,
    ENC_JPEG_THUMBNAIL      = 6,
    ENC_JPEG_THUMBNAIL2     = 7,
} sgks_enc_pic_type_e;

typedef struct __sgks_dsp_bits_info
{
    u32 frame_num;
    u32 PTS;
    u32 start_addr;
    u32 pic_type    :  3;
    u32 level_idc   :  3;
    u32 ref_idc     :  1;
    u32 pic_struct  :  1;
    u32 pic_size    : 24;

    u32 stream_id   :  8;
    u32 session_id  :  4;
    u32 res_1       : 20;
    u32 pjpeg_start_addr;
    u32 pjpeg_size;
    u32 reserved;
} sgks_dsp_bits_info_s;

typedef  struct __sgks_mdi_encode_info
{
    u32 init_flag;
    
    sgks_dsp_bits_info_s *bits_desc_start;
    sgks_dsp_bits_info_s *bits_desc_end;
    sgks_dsp_bits_info_s *bits_desc_read_ptr;
    sgks_dsp_bits_info_s *bits_desc_prefetch_ptr;

    u32 total_pic_encoded_h264_mode;
    u32 total_pic_encoded_mjpeg_mode;
    u32 total_pic_encoded_jpeg_mode;
    u32 h264_pic_counter;
    u32 mjpeg_pic_counter;
    u32 total_pic_counter;
    u32 jpeg_pic_counter;
    
    u32 current_encode_state;
    struct semaphore  sem_frame_counter;
    struct mutex bsb_mem_mutex

}sgks_mdi_encode_info_s;

typedef struct __sgks_user_param
{
	void                  *file;
	sgks_mdi_mmap_s user_mmap;
}sgks_user_param_s;

typedef struct sgks_vi_irq_info
{
	unsigned int    				irq;
	unsigned long   				flags;
	char            				name[32];
	u32             				counter;
	struct proc_dir_entry      		*proc_file;
	struct sgks_sync_proc_hinfo  	proc_hinfo;
	void                       		*callback_data;
	void (*callback)(void *callback_data, u32 counter);
} sgks_vi_irq_info_s;



typedef struct sgks_mdi_dsp_compl
{
    struct completion    dsp_readlog_compl;
    u32  				  dsp_readlog_compl_wait_count;

    struct completion    isp_statis_compl;
    u32  				  isp_statis_compl_wait_count;

    struct completion    cmd_avail_compl;
    u32  				  cmd_avail_compl_wait_count;

    struct completion    decode_compl;
    u32  				 decode_compl_wait_count;

    struct completion    state_change_compl;
    u32  				 state_change_compl_wait_count;

    struct completion	 yuv_to_enc_compl;
    u32                  yuv_to_enc_compl_wait_count;

    struct completion    yuv_to_enc_sync_cmpl;
    atomic_t             wait_yuv_to_enc_sync_done;    

} sgks_mdi_dsp_compl_s;

typedef struct __sgks_mdi_manager
{
    sgks_user_param_s     			user_area;
    sgks_dsp_buffer_config_s 		dsp_buff;
    sgks_isp_buffer_config_s 		isp_buff;
    sgks_mdi_main_mpi_s 			main_mpi;
    sgks_mdi_isp_statistics_s   	isp_statistics;
    sgks_mdi_isp_statistics_pos_s 	isp_user_statistics_pos;
    sgks_mdi_vdec_buff_pos_s		vdec_buff_pos;
    sgks_mdi_vdec_buff_s			vdec_buff;
	sgks_mdi_vdec_decode_info_s		vdec_info;
    sgks_mdi_dsp_status_s           dsp_status;
    sgks_vi_irq_info_s        		vi_irq_list[MAX_VI_IRQ_NUM];/*0:vsync_irq 1:vi_irq 2:icore_last_pixel_irq 3:icore_irq*/
    sgks_mdi_dsp_compl_s			dsp_compl;
	sgks_mdi_yuv_info_s             user_yuv_info;
    sgks_mdi_osdVoInfo_s            osd_voInfo;
    sgks_mdi_jpeg_info_s            jpeg_info;
} sgks_mdi_manager_s;



/********************* dsp ******************/

#define SGKS_DSP_RESULT_SIZE          256

typedef struct sgks_dsp2_info
{
    u32 dsp_cmd_rx; // if DSP had read from cmd buf
    u32 dsp_msg_tx;    // if DSP had written to msg buf

    u32 dsp_histogram_tx: 1; //if DSP has send at least one histogram to ARM
    u32 reserv: 31;
    u32 cmd_seq;
    u32 padding[4];
	u32 dsp_cmd_recv_seq;
} sgks_dsp2_info_s;


typedef struct encode_msg_s
{
	u32 dsp_operation_mode;
	u32 timecode;
	u32 cmd_echo;
	u32 num_cmds;
	u32 aaa_data_fifo_next;
	u32 aaa_data_fifo_size;
	u32 h264_bits_fifo_next;
	u32 h264_bits_fifo_size;
	u32 h264_info_fifo_next;
	u32 h264_info_fifo_size;
	u32 jpeg_bits_fifo_next;
	u32 jpeg_bits_fifo_size;
	u32 jpeg_info_fifo_next;
	u32 jpeg_info_fifo_size;
	u32 raw_pic_addr;
	u32 thumbnail_pic_y_addr;
	u32 thumbnail_pic_uv_addr;
	u32 thumbnail_pic_y_pitch;
	u32 encode_y_pic_addr;
	u32 encode_uv_pic_addr;
	u32 encode_yuv_pitch;
	u32 preview_y_pic_addr;
	u32 preview_uv_pic_addr;
	u32 preview_yuv_pitch;
	u32 total_pic_encoded_h264_mode;
	u32 total_pic_encoded_jpeg_mode;
	u32 total_thumbnail_encoded_jpeg_mode;
	u32 raw_cap_cnt;
	u32 yuv_pic_cnt;
	u32 encode_operation_mode;
	u16 encode_state;
	u16 capture_state;
	u32 pts_val;
#define NO_ERROR            0
#define ILLEGAL_SIGNAL_1    1
	u32 err_code;
	u32 raw_pic_pitch;
	u32 raw_pic_width;
	u32 raw_pic_row;
	u32 yuv_aaa_data_fifo_next;
	u32 yuv_aaa_data_fifo_size;
	u16 re_encode_state[4];
	u32 pjpg_bitBuf_addr;
	u32 pjpg_bitBuf_sz;
	u32 total_screen_thumbnail_encoded_jpeg_mode;
	u32 screen_thumbnail_pic_y_addr;
	u32 screen_thumbnail_pic_uv_addr;
	u32 total_pic_encoded_mjpeg_mode;
	u32 main_me1_addr;
	u32 main_me1_pitch;
	u32 preview_c_me1_addr;
	u32 preview_c_me1_pitch;

	u32 encode_yuv_height;
	u32 encode_yuv_width;
	u32 rescale_y_pic_addr;
	u32 rescale_uv_pic_addr;
	u32 rescale_yuv_pitch;
	u32 rescale_yuv_height;
	u32 rescale_yuv_width;
	u8 rescale_yuv_type;
} encode_msg_t;

typedef enum
{
    SGKS_DEC_IDLE_STATE               = 0x00,
    SGKS_DEC_H264DEC_STATE            = 0x01,
    SGKS_DEC_H264DEC_IDLE_STATE       = 0x02,
    SGKS_DEC_TRANSITION_1_TO_0_STATE  = 0x03,
    SGKS_DEC_TRANSITION_1_TO_2_STATE  = 0x04,
    SGKS_DEC_JPEGSTILL_STATE          = 0x05,
    SGKS_DEC_TRANSITION_5_TO_0        = 0x06,
    SGKS_DEC_MULTISCENE_STATE         = 0x07,
    SGKS_DEC_TRANSITION_7_TO_0_STATE  = 0x08,
    SGKS_DEC_UNKNOWN_STATE            = 0x09
} sgks_decode_state_e;

/**
 * H264/JPEG decoding message
 */
typedef struct decode_msg_s
{
    u32 dsp_operation_mode;
    u32 timecode;
    u32 cmd_echo;
    u32 num_cmds;
    u32 latest_clock_counter;
    u32 latest_pts;
    u32 jpeg_frame_count;
    u32 yuv422_y_addr;
    u32 yuv422_uv_addr;
    u32 h264_bits_fifo_next;
    u32 jpeg_bits_fifo_next;
    u32 decode_state;
    u32 error_status;
    u32 total_error_count;
    u32 decoded_pic_number;
    u32 jpeg_thumbnail_size;
    u32 jpeg_rescale_buf_pitch; /* pitch of scaled JPEG after decoding */
    u16 jpeg_rescale_buf_width;
    u16 jpeg_rescale_buf_height;
    u32 jpeg_rescale_buf_address_y; /* Y address of scaled JPEG after decoding */
    u32 jpeg_rescale_buf_address_uv;
    u32 second_rescale_buf_pitch; /* pitch of scaled JPEG after decoding */
    u16 second_rescale_buf_width;
    u16 second_rescale_buf_height;
    u32 second_rescale_buf_address_y; /* Y address of second scaled after decoding */
    u32 second_rescale_buf_address_uv;
    u32 jpeg_y_addr; /*Y address of decoded JPEG */
    u32 jpeg_uv_addr;
    u32 jpeg_pitch; /* DRAM pitch of decoded JPEG */
    u32 jpeg_width; /* width of decoded JPEG */
    u32 jpeg_height;
    u32 jpeg_capture_count;
    u32 jpeg_screennail_size;
    u32 jpeg_thumbnail_buf_dbase; /*multi scene thumbnail buffer base address*/
    u32 jpeg_thumbnail_buf_pitch; /*buffer pitch of each thumbnail buffer */
    u32 jpeg_large_thumbnail_buf_dbase; /*multi scene large thumbnail buffer base address*/
    u32 jpeg_large_thumbnail_buf_pitch; /*buffer pitch of each large thumbnail buffer */
    u16 jpeg_cabac_message_queue_fullness; /* fullness of cabac message queue */
    u16 jpeg_rescale_message_queue_fullness; /* fullness of rescale message queue */
    u16 yuv422_width;
    u16 yuv422_height;
    u16 yuv422_pitch;
    u16 yuv422_type;
    u16 jpeg_type;
    u16 second_rescale_buf_type;
} decode_msg_t;


typedef struct sgks_crypto_aes_data
{
	u32     data_127_96;
	u32     data_95_64;
	u32     data_63_32;
	u32     data_31_0;
} sgks_crypto_aes_data_s;

typedef struct sgks_crypto_des_data
{
	u32     data_hi;
	u32     data_lo;
} sgks_crypto_des_data_s;

typedef union sgks_crypto_data
{
	u32                     data[4];
	sgks_crypto_des_data_s    des_data;
	sgks_crypto_aes_data_s    aes_data;
} sgks_crypto_data_s;

typedef struct sgks_crypto_case
{
	sgks_crypto_mode_e    mode;
	sgks_crypto_key_s     pkey;
	sgks_crypto_data_s    source;
	sgks_crypto_data_s    enc_dest;
	sgks_crypto_data_s    dec_dest;
} sgks_crypto_case_s;

typedef union
{
	// CRYPTO_DES_Interrupt
	u32 all;
	struct
	{
		u32 en          :  1;
		u32             : 31;
	} bitc;
} sgks_crypto_des_interrupt_s;

/**errcode**/
#define SGKS_SUCCESS                    (0)  
#define SGKS_FAIL                        (-1)  
#define SGKS_OPERATION_ERR_DATA        (-10010001) 
#define SGKS_OPERATION_ERR_ID          (-10010002) 
#define SGKS_OPERATION_ERR_SYS         (-10010003) 
#define SGKS_OPERATION_ERR_UNMMAP      (-10010004) 
#define SGKS_OPERATION_ERR_DEFCMD      (-10010005) 
#define SGKS_OPERATION_ERR_CMDMODE     (-10010006) 

#endif

